package thread;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

// TCP 版本的回显服务器
public class ThreadWork5 {

    private ServerSocket serverSocket = null;

    // 构造端口
    public ThreadWork5(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }

    public void start() throws IOException{
        System.out.println("启动服务器！！！");
        // 使用 cilentSocket 可具体的客户端进行交互
        Socket cilentSocket = serverSocket.accept();
        processsConnection(cilentSocket);
    }

    // 使用这个方法来处理一个连接
    // 这一个连接对应到一个客户端，但是这里可能会涉及到多次交互
    private void processsConnection(Socket cilentSocket) {
        System.out.printf("[%s:%d]客户端上线！\n", cilentSocket.getInetAddress().toString(), cilentSocket.getPort());
        // 基于上述 scoket 对象和客户端进行交互
        try (InputStream inputStream = cilentSocket.getInputStream();
             OutputStream outputStream = cilentSocket.getOutputStream()){
            // 多个请求要用 循环
            while (true) {
                // 1.读取请求
                Scanner scanner = new Scanner(inputStream);
                if (!scanner.hasNext()) {
                    // 次数读取完毕 - 即客户端关闭了连接
                    System.out.printf("[%s：%d 客户端下线！\n", cilentSocket.getInetAddress().toString(),
                            cilentSocket.getPort());
                    break;
                }
                String requst = scanner.next();

                // 2.根据请求构造响应
                String response = process(requst);

                // 返回响应结果
                //  OutputStream 不能写字符串,可以放到 PrintWriter
                PrintWriter printWriter = new PrintWriter(outputStream);
                printWriter.println(response);
                // 刷新缓冲区，保证数据确实是发送出去了
                printWriter.flush();
                System.out.printf("[%s:%d] rep: %s; reap: %s \n", cilentSocket.getInetAddress().toString(),
                        cilentSocket.getPort(), requst, response);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                cilentSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException{
        ThreadWork5 threadWork5 = new ThreadWork5(9090);
        // 启动
        threadWork5.start();
    }
}
